package com.alcatel_lucent.scalastudy.model

/**
 * Created with IntelliJ IDEA.
 * User: Guoshun Wu
 * Date: 13-6-6
 * Time: 下午8:48
 */
class Rational(n: Int, d: Int = 1) extends Ordered[Rational]{
  require(d != 0)
  private val g = gcd(n.abs, d.abs)

  val numerator = n / g
  val denominator = d / g

  //  def this(n: Int) = this(n, 1)
  //  implicit def intToRational(x:Int) = new Rational(x)

  def +(that: Rational) = new Rational(numerator * that.denominator + that.numerator * denominator, denominator * that.denominator)

  def +(i: Int) = new Rational(numerator + i * denominator, denominator)

  def -(that: Rational) = new Rational(numerator * that.denominator - that.numerator * denominator, denominator * that.denominator)

  def -(i: Int) = new Rational(numerator - i * denominator, denominator)

  def *(that: Rational) = new Rational(numerator * that.numerator, denominator * that.denominator)

  def *(i: Int): Rational = this * new Rational(i)

  def /(that: Rational) = this * that.reciprocal

  def /(i: Int): Rational = this / new Rational(i)

  def compare(that: Rational) = this.numerator * that.denominator - that.numerator * this.denominator

  def reciprocal = new Rational(denominator, numerator)

  override def equals(obj: Any) = obj.isInstanceOf[Rational] &&
    obj.asInstanceOf[Rational].numerator == numerator && obj.asInstanceOf[Rational].denominator == denominator

  override def toString = if (1 == denominator) String.valueOf(numerator) else s"${numerator}/${denominator}"

  private def gcd(a: Int, b: Int): Int = if (b == 0) a else gcd(b, a % b)
}
